home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pas_all.zip / TI174.ASC < prev    next >
Text File  |  1992-09-02  |  12KB  |  463 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  9.   VERSION  :  3.01A
  10.        OS  :  PC DOS
  11.      DATE  :  August 1, 1986                           PAGE  :  1/7
  12.  
  13.     TITLE  :  Files Open Extend
  14.  
  15.  
  16.  
  17.  
  18.   The following is public domain information that has been uploaded
  19.   to our Forum on CompuServe. As a courtesy to our users that do
  20.   not have immediate access to CompuServe, Technical Support
  21.   distributes these routines free of charge.
  22.  
  23.   However, because these routines are public domain programs, not
  24.   developed by Borland International, we are unable to provide any
  25.   technical support or assistance using these routines. If you need
  26.   assistance using these routines, or are experiencing difficu
  27.  
  28.   Written by:
  29.   Randy Forgaard, CompuServe 70307,521
  30.   Many thanks to Bela Lubkin (CompuServe 76703,3015) for
  31.   masterminding this idea, and Kim Kokkonen (CompuServe 72457,2131)
  32.   for helping me debug it. For more discussion of Handle Tables and
  33.   the implementation of DOS redirection, please see Stan Mitchell,
  34.   "Co
  35.  
  36.   Due to a limitation of DOS, Turbo Pascal version 3.0 only allows
  37.   up to 15 files at a time to be open. The following method allows
  38.   you to have up to 96 files open simultaneously under DOS 2.0 or
  39.   2.1, or 252 files open simultaneously under DOS 3.0 or grea
  40.  
  41.   TO USE THIS TECHNIQUE:
  42.  
  43.   You need the routines and global declarations below. Everywhere
  44.   in your program that you Reset or Rewrite a file "f" for the
  45.   first time, insert an "OpenExtend(f);" invocation immediately
  46.   after the Reset or Rewrite. Each time your program calls one of
  47.   Turb
  48.  
  49.   At the top of your program, prior to the "program" statement, put
  50.   the compiler directive {$F252}. (You may use a value smaller than
  51.   252 if you wish. Under DOS 2.0/2.1, values above 96 have
  52.   no additional benefit. Each larger value for the {$F} directive
  53.   uses 2 additional bytes in the program's global data space.) The
  54.   value you specify for the {$F} directive is the maximum number of
  55.   files you will be able to have open at the same time in your
  56.  
  57.   Edit your CONFIG.SYS file (see the DOS manual for details) so
  58.   that it includes a line that says "FILES=XXX". XXX should be a
  59.   number that is 3 greater than the value you specified for the
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  75.   VERSION  :  3.01A
  76.        OS  :  PC DOS
  77.      DATE  :  August 1, 1986                           PAGE  :  2/7
  78.  
  79.     TITLE  :  Files Open Extend
  80.  
  81.  
  82.  
  83.  
  84.   {$F} directive (larger values will provide no additional benefit
  85.   wit
  86.  
  87.   THE TECHNICAL DETAILS:
  88.  
  89.   Much of the following information is not documented in the DOS
  90.   Technical Reference manual.
  91.  
  92.   Under DOS 1.0 and 1.1, all files were accessed via File Control
  93.   Blocks (FCB's). There was no limit to the number of FCB's that a
  94.   program could use, so there was no limit to the number of files
  95.   open simultaneously.
  96.  
  97.   Under DOS 2.0 and greater, an alternate (and preferable) method
  98.   of accessing files was introduced which uses a 2-byte integer
  99.   called a "handle" to refer to a file. A "handle" file is
  100.   described using a data structure called a Device Control Block
  101.   (DCB). Ho
  102.  
  103.   So that I/O redirection can be supported, the DCB numbers are not
  104.   used directly when accessing files. Instead, a file "handle" is
  105.   used. A "handle" is an index into a 20-byte array, called the
  106.   Handle Table, which is located at offset 18H of the Program Seg
  107.  
  108.   Every time a new handle file is opened, a new handle gets used.
  109.   Since there are only 20 slots available in the Handle Table for a
  110.   program, DOS only allows a "process" to have a maximum of 20 file
  111.   handles in use simultaneously (and the first 5 entries are
  112.  
  113.   The size of the DCB Table (i.e., the maximum number of
  114.   files/devices that can be open simultaneously in the whole
  115.   computer) is controlled by the FILES=XXX entry in the CONFIG.SYS
  116.   file. The minimum number of slots is 8. Under DOS 2.0/2.1, the
  117.   maximum numbe
  118.  
  119.   A single program can use all of the DCB's in the DCB Table
  120.   (except for the 3 reserved by DOS) all on its own, by effectively
  121.   bypassing the Handle Table in the PSP, except on a temporary
  122.   basis. The program can accomplish this feat by using, say, only
  123.   one e
  124.  
  125.   The OpenExtend, UnExtend, and ReExtend routines below use this
  126.   technique. OpenExtend(f) is used on a previously-opened file,
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  141.   VERSION  :  3.01A
  142.        OS  :  PC DOS
  143.      DATE  :  August 1, 1986                           PAGE  :  3/7
  144.  
  145.     TITLE  :  Files Open Extend
  146.  
  147.  
  148.  
  149.  
  150.   "f." It removes f's DCB number from the Handle Table, and stores
  151.   that DCB number in place of the file handle in Turbo's data struc
  152.  
  153.   To obtain the address of the Handle Table, which is at offset 18H
  154.   in the PSP, the program needs to find the address of its PSP.
  155.   Normally, this is very easy: when DOS loads a .COM file, the
  156.   address of the PSP is just CS:0000. Using CS:0000 in this manner
  157.   w
  158.  
  159.   To allow the program to work correctly both when running in
  160.   memory and when run as a .COM file, we use the DOS function call
  161.   62H, "Get Program Segment Prefix Address (PSP)." This function
  162.   call is available in DOS 3.0 and higher. There is an identical
  163.   func
  164.   To decide whether to use function 51H or 62H, we call DOS
  165.   function 30H, "Get DOS Version Number," to determine which
  166.   version of DOS is running. This strategy for obtaining the Handle
  167.   Table address is implemented in the GetHandleTableAddr function,
  168.   below,
  169.  
  170.   Note: This technique will not interfere with overlays in your
  171.   program (since it only uses the Handle Table slot temporarily),
  172.   provided that your program leaves at least one DCB available for
  173.   use by the Turbo run-time library to read in overlay files.
  174.  
  175.   {$F252}
  176.  
  177.   const
  178.     LastHandle = 19;    {Highest-numbered handle}
  179.     UnusedHandle = $FF; {DcbTable entry that denotes an unused
  180.   handle}
  181.   type
  182.     HandleTable = array[0..LastHandle] of Byte;
  183.     HandleTablePtr = ^HandleTable;
  184.   const
  185.     TablePtrOk: Boolean = false; {"True" iff TablePtr is
  186.   initialized}
  187.   var
  188.     TablePtr: HandleTablePtr; {Points to Handle Table for this
  189.   process}
  190.     SaveDcb:  Byte;  {Temporary variable for a DCB number during a
  191.   function
  192.                                   call}
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  207.   VERSION  :  3.01A
  208.        OS  :  PC DOS
  209.      DATE  :  August 1, 1986                           PAGE  :  4/7
  210.  
  211.     TITLE  :  Files Open Extend
  212.  
  213.  
  214.  
  215.  
  216.   {Internal  routine.   Returns  the address of the  Handle  Table,
  217.   which is at offset 18H in the PSP.}
  218.  
  219.   function GetHandleTableAddr: HandleTablePtr;
  220.   var
  221.     regs: record
  222.                   case Integer of
  223.                     1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags:
  224.   Integer);
  225.                     2: (AL, AH, BL, BH, CL, CH, DL, DH: Byte)
  226.                   end;
  227.  
  228.   begin
  229.     regs.AH := $30;
  230.     MsDos(regs);      {Get DOS version number}
  231.     case regs.AL of
  232.       0: begin
  233.                   writeln('This program only works with DOS 2.0 and
  234.   higher');
  235.                   Halt
  236.             end;
  237.       2: regs.AH := $51; {Undocumented, but works with DOS 2.0/2.1
  238.   (and 3.X)}
  239.     else regs.AH := $62  {Works with DOS 3.0 and higher}
  240.     end;
  241.     MsDos(regs);      {Get PSP address}
  242.     GetHandleTableAddr := Ptr(regs.BX, $18)
  243.   end {GetHandleTableAddr};
  244.  
  245.  
  246.   {Causes "f" to become an "extended" file; i.e., to remain open
  247.   without using up any file handles. The parameter "f" must be any
  248.   Turbo file;  e.g., a File, a File of Byte, a File of Foo, Text,
  249.   etc. This routine should be called immediately after the Reset
  250.  
  251.   procedure OpenExtend (var f);
  252.   var
  253.     handle: Integer absolute f;
  254.   begin
  255.     if not TablePtrOk then
  256.       begin
  257.            TablePtr := GetHandleTableAddr;
  258.            TablePtrOk := true
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  273.   VERSION  :  3.01A
  274.        OS  :  PC DOS
  275.      DATE  :  August 1, 1986                           PAGE  :  5/7
  276.  
  277.     TITLE  :  Files Open Extend
  278.  
  279.  
  280.  
  281.  
  282.       end;
  283.     SaveDcb := TablePtr^[handle];
  284.     TablePtr^[handle] := UnusedHandle;
  285.     handle := SaveDcb
  286.   end {OpenExtend};
  287.  
  288.  
  289.   {Unextends the extended file "f," so that it can be used by any
  290.   of Turbo's built-in file routines. Note that "f" must have been
  291.   converted  to an extended file by OpenExtend before invoking
  292.   UnExtend(f). After calling UnExtend, and then invoking the Turbo
  293.   f
  294.  
  295.   procedure UnExtend (var f);
  296.   var
  297.     handle: Integer absolute f;
  298.   begin
  299.     SaveDcb := TablePtr^[LastHandle];
  300.     TablePtr^[LastHandle] := Lo(handle);
  301.     handle := LastHandle
  302.   end {UnExtend};
  303.  
  304.  
  305.   {Re-extends "f" into an extended file. Note that "f" must have
  306.   been converted to an extended file by OpenExtend, and then
  307.   unextended  using UnExtend, before "f" can re-extended using
  308.   ReExtend.  ReExtend(f) should be invoked immediately after any
  309.   normal Tu
  310.  
  311.   procedure ReExtend (var f);
  312.   var
  313.     handle: Integer absolute f;
  314.   begin
  315.     handle := TablePtr^[LastHandle];
  316.     TablePtr^[LastHandle] := SaveDcb
  317.   end {ReExtend};
  318.  
  319.   {Example program -- This program opens as many Text files as it
  320.   can,  until DOS runs out of room in its DCB Table. It then
  321.   reports how many files were successfully opened, writes a line to
  322.   each of them, then closes and erases each of them. Note: The
  323.   value
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  339.   VERSION  :  3.01A
  340.        OS  :  PC DOS
  341.      DATE  :  August 1, 1986                           PAGE  :  6/7
  342.  
  343.     TITLE  :  Files Open Extend
  344.  
  345.  
  346.  
  347.  
  348.   This program takes a while to run, due to the heavy disk I/O, so
  349.   running it on a hard disk (or, even better, a RAM disk) is
  350.   recommended.  Make sure that you are running the program in a
  351.   subdirectory, so that you don't run up against the DOS limit on
  352.   the n
  353.  
  354.   const
  355.     MaxCount = 255;
  356.   var
  357.     num: string[6];
  358.     f: array[1..MaxCount] of Text;
  359.     i, count: Integer;
  360.     result: Byte;
  361.   begin
  362.     writeln('Opening files...');
  363.     i := 0;
  364.     repeat
  365.       i := i + 1;
  366.       Str(i, num);
  367.       Assign(f[i], 'junk' + num + '.txt');
  368.       {$I-} Rewrite(f[i]); {$I+}
  369.       result := IOResult;
  370.       if result = 0 then OpenExtend(f[i])
  371.     until result <> 0;
  372.     count := i - 1;
  373.     writeln('Successfully opened ', count, ' files at the same
  374.   time.  ',
  375.                   'Writing to each file...');
  376.     for i := 1 to count do
  377.       begin
  378.            UnExtend(f[i]);
  379.            writeln(f[i], 'This is a test');
  380.            ReExtend(f[i])
  381.       end;
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.   PRODUCT  :  Turbo Pascal                           NUMBER  :  174
  405.   VERSION  :  3.01A
  406.        OS  :  PC DOS
  407.      DATE  :  August 1, 1986                           PAGE  :  7/7
  408.  
  409.     TITLE  :  Files Open Extend
  410.  
  411.  
  412.  
  413.  
  414.     writeln('Closing and erasing each file...');
  415.     for i := 1 to count do
  416.       begin
  417.            UnExtend(f[i]);
  418.            Close(f[i]);
  419.            Erase(f[i]);
  420.            ReExtend(f[i])
  421.       end;
  422.     writeln('Done.')
  423.   end.
  424.   (**)
  425.  
  426.  
  427.   DISCLAIMER: You have the right to use this technical information
  428.   subject to the terms of the No-Nonsense License Statement that
  429.   you received with the Borland product to which this information
  430.   pertains.
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.